package com.jyy.prefabricated.service;

import com.jyy.prefabricated.dto.StudentExerciseDto;
import com.jyy.prefabricated.entity.*;
import com.jyy.prefabricated.enums.ExerciseStatusEnum;
import com.jyy.prefabricated.exception.CustomException;
import com.jyy.prefabricated.mapper.*;
import com.jyy.prefabricated.utils.DateUtils;
import com.jyy.prefabricated.vo.ExamResultVo;
import com.jyy.prefabricated.vo.StudentExerciseQuestionVo;
import com.jyy.prefabricated.vo.StudentExerciseVo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @version 1.0.0
 * @author: zjj
 */
@Service
public class StudentExerciseService {

    @Resource
    private StudentExerciseMapper studentExerciseMapper;

    @Resource
    private QuestionMapper questionMapper;

    @Resource
    private StudentExerciseQuestionMapper studentExerciseQuestionMapper;

    @Resource
    private StudentErrorQuestionMapper studentErrorQuestionMapper;

    @Resource
    private ExamPaperMapper paperMapper;

    /**
     * 新增练习
     *
     * @param dto
     * @return
     */
    public Integer insert(StudentExerciseDto dto) {
        List<StudentExerciseVo> list = studentExerciseMapper.selectExerciseVoByStudentIdAndDto(dto);
        if (list != null && list.size() > 0) {
            List<Integer> studentExerciseIds = list.stream().map(e -> e.getStudentExerciseId()).collect(Collectors.toList());
            for (Integer id : studentExerciseIds) {
                studentExerciseQuestionMapper.deleteByStudentExerciseId(id);
                studentExerciseMapper.deleteByPrimaryKey(id);
            }

        }
        StudentExercise studentExercise = new StudentExercise();
        studentExercise.setQuestionBankId(dto.getQuestionBankId());
        studentExercise.setStudentId(dto.getStudentId());
        studentExercise.setExerciseStatus(ExerciseStatusEnum.DOING.getValue());
        studentExercise.setExamPaperId(dto.getExamPaperId());
        studentExerciseMapper.insert(studentExercise);
        Integer studentExerciseId = studentExercise.getId();
//        initExercisePaperDetail(dto.getQuestionBankId(), studentExerciseId);
        initExercisePaperDetailByExamPaperId(dto.getExamPaperId(), studentExerciseId);
        return studentExerciseId;
    }


    /**
     * 初始化练习试题
     *
     * @param examPaperId
     */
    public void initExercisePaperDetailByExamPaperId(Integer examPaperId, Integer studentExerciseId) {
        List<StudentExerciseQuestion> studentExerciseQuestions = new ArrayList<>();

        ExamPaper examPaper = paperMapper.selectByPrimaryKey(examPaperId);
        List<Question> questionList = new ArrayList<>();
        if (examPaper.getAreas().size() > 0) {
            for (ExamPaperArea examPaperArea : examPaper.getAreas()) {
                //随机出题
                if (examPaperArea.getRules().size() > 0) {
                    if (examPaperArea.getExtractingStatus() == 0) {
                        for (ExamPaperAreaRule examPaperAreaRule : examPaperArea.getRules()) {
                            List<Question> alllist = questionMapper.selectByParams(examPaperAreaRule.getQuestionBankId(), examPaperAreaRule.getQuestionType(), examPaperAreaRule.getStemType(), null, null, examPaperAreaRule.getDifficulty(), null, null, null);
                            Collections.shuffle(alllist);
                            //选取随机的集合元素
                            if (examPaperAreaRule.getQuestionCount() > alllist.size()) {
                                examPaperAreaRule.setQuestionCount(alllist.size());
                            }
                            List<Question> randomSeries = alllist.subList(0, examPaperAreaRule.getQuestionCount());
                            for (int i = 0; i < examPaperAreaRule.getQuestionCount(); i++) {
                                if (randomSeries != null && i < randomSeries.size()) {
                                    randomSeries.get(i).setGrade(examPaperAreaRule.getGrade());
                                }

                            }
                            questionList.addAll(randomSeries);
                        }
                    } else {
                        for (ExamPaperAreaRule examPaperAreaRule : examPaperArea.getRules()) {
                            List<Question> alllist = questionMapper.selectByParams(examPaperAreaRule.getQuestionBankId(), examPaperAreaRule.getQuestionType(), examPaperAreaRule.getStemType(), null, null, examPaperAreaRule.getDifficulty(), null, null, null);
                            //选取随机的集合元素
                            if (examPaperAreaRule.getQuestionCount() > alllist.size()) {
                                examPaperAreaRule.setQuestionCount(alllist.size());
                            }
                            List<Question> randomSeries = alllist.subList(0, examPaperAreaRule.getQuestionCount());
                            for (int i = 0; i < examPaperAreaRule.getQuestionCount(); i++) {
                                if (randomSeries != null && i < randomSeries.size()) {
                                    randomSeries.get(i).setGrade(examPaperAreaRule.getGrade());
                                }
                            }
                            questionList.addAll(randomSeries);
                        }
                    }
                }
            }
        }
        int i = 0;
        for (Question question : questionList) {
            i++;
            StudentExerciseQuestion studentExerciseQuestion = new StudentExerciseQuestion();
            studentExerciseQuestion.setQuestionId(question.getId());
            studentExerciseQuestion.setStudentExerciseId(studentExerciseId);
            studentExerciseQuestion.setScore(question.getGrade());
            studentExerciseQuestion.setSort(i);
            studentExerciseQuestions.add(studentExerciseQuestion);
        }
        if (studentExerciseQuestions != null && studentExerciseQuestions.size() > 0) {
            studentExerciseQuestionMapper.batchInsert(studentExerciseQuestions);
        }

    }

    /**
     * 初始化练习试题
     *
     * @param questionBankId
     */
    public void initExercisePaperDetail(Integer questionBankId, Integer studentExerciseId) {
        List<Question> questions = questionMapper.selectByParams(questionBankId, null, null, null, null, null, null, null, null);
        List<StudentExerciseQuestion> studentExerciseQuestions = new ArrayList<>();
        int i = 0;
        for (Question question : questions) {
            i++;
            StudentExerciseQuestion studentExerciseQuestion = new StudentExerciseQuestion();
            studentExerciseQuestion.setQuestionId(question.getId());
            studentExerciseQuestion.setStudentExerciseId(studentExerciseId);
            studentExerciseQuestion.setSort(i);
            studentExerciseQuestions.add(studentExerciseQuestion);
        }
        studentExerciseQuestionMapper.batchInsert(studentExerciseQuestions);
    }

    /**
     * 结束练习
     *
     * @param studentExerciseId
     */
    public ExamResultVo finishExercise(Integer studentExerciseId) {
        ExamResultVo resultVo = new ExamResultVo();
        StudentExercise studentExercise = studentExerciseMapper.selectByPrimaryKey(studentExerciseId);
        if (ExerciseStatusEnum.AFTER.getValue().equals(studentExercise.getExerciseStatus())) {
            throw new CustomException("当前练习已结束");
        }
        // long now = DateUtils.getUct8NowDate().getTime();
        //Long useTime = now - studentExercise.getCreateTime().getTime();
        studentExercise.setExerciseStatus(ExerciseStatusEnum.AFTER.getValue());

        int now = getSecondTimestamp(DateUtils.getUct8NowDate());
        int createTime = getSecondTimestamp(studentExercise.getCreateTime());
        int useTime = now - createTime;
        studentExercise.setUseTime(useTime);
        studentExerciseMapper.updateByPrimaryKeySelective(studentExercise);
        List<StudentExerciseQuestion> questions = studentExerciseQuestionMapper.selectByStudentExerciseId(studentExerciseId);
        Integer rightCount = 0;
        Integer errorCount = 0;
        Integer unAnswerCount = 0;
        Integer answerCount = 0;
        List<StudentErrorQuestion> studentErrorQuestions = new ArrayList<>();
        for (StudentExerciseQuestion question : questions) {
            if (question.getAnswer() == null) {
                unAnswerCount++;
            } else {
                answerCount++;
                if (question.getIfRight()) {
                    rightCount++;
                } else {
                    errorCount++;
                    //新增错题到错题集列表
                    StudentErrorQuestion errorQuestion = new StudentErrorQuestion();
                    errorQuestion.setAnswer(question.getAnswer());
                    //  errorQuestion.setQuestionBankId(studentExercise.getQuestionBankId());
                    errorQuestion.setExamPaperId(studentExercise.getExamPaperId());
                    errorQuestion.setQuestionId(question.getQuestionId());
                    errorQuestion.setStudentId(studentExercise.getStudentId());
                    studentErrorQuestions.add(errorQuestion);
                }
            }
        }
        //保存错题集
        saveStudentErrorQuestion(studentErrorQuestions);
        resultVo.setUnAnswerCount(unAnswerCount);
        resultVo.setAnswerCount(answerCount);
        resultVo.setRightCount(rightCount);
        resultVo.setErrorCount(errorCount);
        return resultVo;
    }

    /**
     * 获取精确到秒的时间戳
     *
     * @return
     */
    public static int getSecondTimestamp(Date date) {
        if (null == date) {
            return 0;
        }
        String timestamp = String.valueOf(date.getTime());
        int length = timestamp.length();
        if (length > 3) {
            return Integer.valueOf(timestamp.substring(0, length - 3));
        } else {
            return 0;
        }
    }


    /**
     * 保存学员答错的题目
     *
     * @param studentErrorQuestions
     */
    public void saveStudentErrorQuestion(List<StudentErrorQuestion> studentErrorQuestions) {
        if (studentErrorQuestions.size() > 0) {
            List<StudentErrorQuestion> result = new ArrayList<>();
            List<StudentExerciseQuestionVo> questions = studentErrorQuestionMapper.selectQuestionVoByExamPaperIdAndStudentId(studentErrorQuestions.get(0).getExamPaperId(), studentErrorQuestions.get(0).getStudentId());
            List<Integer> questionIdsList = questions.stream().map(e -> e.getQuestionId()).collect(Collectors.toList());
            for (StudentErrorQuestion studentErrorQuestion : studentErrorQuestions) {
                if (!questionIdsList.contains(studentErrorQuestion.getQuestionId())) {
                    result.add(studentErrorQuestion);
                }
            }
            // studentErrorQuestions.removeAll(questionIdsList);
            if (result.size() > 0) {
                studentErrorQuestionMapper.batchInsert(result);

            }
        }
    }

    /**
     * 更新
     *
     * @param studentExercise
     * @return
     */
    public int update(StudentExercise studentExercise) {
        if (studentExercise.getId() == null) {
            throw new CustomException("参数id不能为空");
        }
        return studentExerciseMapper.updateByPrimaryKeySelective(studentExercise);
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    public int delete(Integer id) {
        return studentExerciseMapper.deleteByPrimaryKey(id);
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    public StudentExercise selectById(Integer id) {
        return studentExerciseMapper.selectByPrimaryKey(id);
    }

    /**
     * 查询学员的练习信息
     *
     * @param studentId 学员id
     * @return
     */
    public List<StudentExerciseVo> selectExerciseVoByStudentId(Integer studentId) {
        return studentExerciseMapper.selectExerciseVoByStudentId(studentId);
    }

    /**
     * 查询学员的练习列表
     *
     * @param dto 学员id
     * @return
     */
    public List<StudentExerciseVo> selectExerciseVoByStudentIdAndDto(StudentExerciseDto dto) {
        List<StudentExerciseVo> result = studentExerciseMapper.selectExerciseVoByStudentIdAndDto(dto);
        if (result != null && result.size() > 0) {
            for (StudentExerciseVo vo : result) {
                List<StudentExerciseQuestionVo> questions = studentExerciseQuestionMapper.selectQuestionVoByStudentExerciseId(vo.getStudentExerciseId());
                vo.setQuestionCount(questions.size());

                List<StudentExerciseQuestionVo> errorQuestions = studentErrorQuestionMapper.selectQuestionVoByExamPaperIdAndStudentId(vo.getExamPaperId(), dto.getStudentId());
                vo.setErrorCount(errorQuestions.size());
                if (ExerciseStatusEnum.AFTER.getValue().equals(vo.getExerciseStatus())) {
                    vo.setTotalScore(questions.stream().mapToDouble(StudentExerciseQuestionVo::getScore).sum());
                }
            }
        }
        return result;
    }


    /**
     * 查询学员的错题练习列表
     *
     * @param dto 学员id
     * @return
     */
    public List<StudentExerciseVo> selectExerciseVoByStudentIdAndParam(StudentExerciseDto dto) {
        List<StudentErrorQuestion> list = studentErrorQuestionMapper.selectExamPaperIdByStudentId(dto.getStudentId());
        List<Integer> examPaperIdList = list.stream().map(e -> e.getExamPaperId()).collect(Collectors.toList());


        List<StudentExerciseVo> result = new ArrayList<>();
        for (Integer examPaperId : examPaperIdList) {
            StudentExerciseVo studentExerciseVo = new StudentExerciseVo();
            ExamPaper examPaper = paperMapper.selectByPrimaryKey(examPaperId);
            List<StudentExerciseQuestionVo> errorQuestions = studentErrorQuestionMapper.selectQuestionVoByExamPaperIdAndStudentId(examPaperId, dto.getStudentId());
            studentExerciseVo.setQuestionCount(errorQuestions.size());
            studentExerciseVo.setExamPaperId(examPaperId);
            studentExerciseVo.setName(examPaper.getName());
            studentExerciseVo.setExerciseStatus(ExerciseStatusEnum.AFTER.getValue());
            result.add(studentExerciseVo);
        }
        return result;
    }
}
